package org.fengling.readingplatform.novel.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;


@Configuration
public class ThreadPoolConfig {

    @Bean("contentThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor getContentThreadPoolTaskExecutor(){
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程数
        taskExecutor.setCorePoolSize(10);
        // 线程池维护线程的最大数据，只有在缓冲队列满了之后才会申请超出核心线程数的线程
        taskExecutor.setMaxPoolSize(100);
        // 缓存队列
        taskExecutor.setQueueCapacity(15);
        // 允许的空闲时间，当超过了核心线程数之外的线程在空闲时间到达之后会被销毁
        taskExecutor.setKeepAliveSeconds(200);
        // 异步方法内部线程名称
        taskExecutor.setThreadNamePrefix("content专用");

        // 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
        // 通常有以下四种策略
        // ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
        // ThreadPoolExecutor.DiscardPolicy:也是丢弃任务，但是不抛出异常
        // ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务，然后重新尝试执行任务(重复此过程)
        // ThreadPoolExecutor.CallerRunsPolicy:重新添加当前的任务，自动重复execute()方法，直到成功

        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 任务都完成再关闭线程池
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 任务初始化
        taskExecutor.initialize();

        return taskExecutor;
    }

}
